home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / editors / emacs / xemacs / xemacs-1.006 / xemacs-1 / lib / xemacs-19.13 / lisp / prim / subr.el < prev    next >
Encoding:
Text File  |  1995-08-18  |  21.9 KB  |  670 lines

  1. ;;; subr.el --- basic lisp subroutines for XEmacs
  2.  
  3. ;;; Copyright (C) 1985, 1986, 1992, 1994 Free Software Foundation, Inc.
  4. ;;; Copyright (C) 1995 Tinker Systems and INS Engineering Corp.
  5. ;;; Copyright (C) 1995 Sun Microsystems.
  6.  
  7. ;; This file is part of XEmacs.
  8.  
  9. ;; XEmacs is free software; you can redistribute it and/or modify it
  10. ;; under the terms of the GNU General Public License as published by
  11. ;; the Free Software Foundation; either version 2, or (at your option)
  12. ;; any later version.
  13.  
  14. ;; XEmacs is distributed in the hope that it will be useful, but
  15. ;; WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17. ;; General Public License for more details.
  18.  
  19. ;; You should have received a copy of the GNU General Public License
  20. ;; along with XEmacs; see the file COPYING.  If not, write to the Free
  21. ;; Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  
  23. ;;; Synched up with: FSF 19.28.
  24.  
  25. ;;; Code:
  26.  
  27.  
  28. ;;;; Lisp language features.
  29.  
  30. (defmacro lambda (&rest cdr)
  31.   "Return a lambda expression.
  32. A call of the form (lambda ARGS DOCSTRING INTERACTIVE BODY) is
  33. self-quoting; the result of evaluating the lambda expression is the
  34. expression itself.  The lambda expression may then be treated as a
  35. function, i. e. stored as the function value of a symbol, passed to
  36. funcall or mapcar, etcetera.
  37. ARGS should take the same form as an argument list for a `defun'.
  38. DOCSTRING should be a string, as described for `defun'.  It may be omitted.
  39. INTERACTIVE should be a call to the function `interactive', which see.
  40. It may also be omitted.
  41. BODY should be a list of lisp expressions."
  42.   ;; Note that this definition should not use backquotes; subr.el should not
  43.   ;; depend on backquote.el.
  44.   ;; #### - I don't see why.  So long as backquote.el doesn't use anything
  45.   ;; from subr.el, there's no problem with using backquotes here.  --Stig 
  46.   (list 'function (cons 'lambda cdr)))
  47.  
  48. ;; FSF19 emits calls to defalias instead of fset in .elc files.
  49. (define-function 'defalias 'define-function)
  50. (define-function 'not 'null)
  51. (define-function 'eql 'eq)
  52. (if (not (fboundp 'numberp))
  53.     (define-function 'numberp 'integerp)) ; different when floats
  54.  
  55.  
  56. ;;;; Hook manipulation functions.
  57.  
  58. (defun run-hooks (&rest hooklist)
  59.   "Takes hook names and runs each one in turn.  Major mode functions use this.
  60. Each argument should be a symbol, a hook variable.
  61. These symbols are processed in the order specified.
  62. If a hook symbol has a non-nil value, that value may be a function
  63. or a list of functions to be called to run the hook.
  64. If the value is a function, it is called with no arguments.
  65. If it is a list, the elements are called, in order, with no arguments."
  66.   (while hooklist
  67.     (let ((sym (car hooklist)))
  68.       (and (boundp sym)
  69.        (symbol-value sym)
  70.        (let ((value (symbol-value sym)))
  71.          (if (and (listp value) (not (eq (car value) 'lambda)))
  72.          (while value
  73.            (funcall (car value))
  74.            (setq value (cdr value)))
  75.            (funcall value)))))
  76.     (setq hooklist (cdr hooklist))))
  77.  
  78. ;; FSFmacs says:
  79. ;; It is best not to depend on the value return by `run-hook-with-args',
  80. ;; as that may change.
  81.  
  82. (defun run-hook-with-args (hook &rest args)
  83.   "Run HOOK with the specified arguments ARGS.
  84. HOOK should be a symbol, a hook variable.  If HOOK has a non-nil
  85. value, that value may be a function or a list of functions to be
  86. called to run the hook.  If the value is a function, it is called with
  87. the given arguments and its return value is returned.  If it is a
  88. list, the elements are called, in order, with the given arguments,
  89. and a list of the each function's return value is returned."
  90.   (and (boundp hook)
  91.        (symbol-value hook)
  92.        (let ((value (symbol-value hook)))
  93.      (if (and (listp value) (not (eq (car value) 'lambda)))
  94.          (mapcar #'(lambda (foo) (apply foo args))
  95.              value)
  96.        (apply value args)))))
  97.  
  98. (defun run-special-hook-with-args (hook &rest args)
  99.   "Run HOOK with the specified arguments, returning the first non-nil value.
  100. HOOK should be a symbol, a hook variable.  If HOOK has a non-nil
  101. value, that value may be a function or a list of functions to be
  102. called to run the hook.  If the value is a function, it is called with
  103. the given arguments and its return value is returned.  If it is a
  104. list, the elements are called, in order, with the given arguments,
  105. until one of them returns non-nil, and this value is returned."
  106.   (and (boundp hook)
  107.        (symbol-value hook)
  108.        (let ((value (symbol-value hook)))
  109.      (if (and (listp value) (not (eq (car value) 'lambda)))
  110.          (let (retval)
  111.            (while (and value
  112.                (not (setq retval (apply (car value) args))))
  113.          (setq value (cdr value)))
  114.            retval)
  115.        (apply value args)))))
  116.  
  117. ;; Tell C code how to call this function.
  118. (setq run-hooks 'run-hooks)
  119.  
  120. (defun add-hook (hook function &optional append)
  121.   "Add to the value of HOOK the function FUNCTION.
  122. FUNCTION is not added if already present.
  123. FUNCTION is added (if necessary) at the beginning of the hook list
  124. unless the optional argument APPEND is non-nil, in which case
  125. FUNCTION is added at the end.
  126.  
  127. HOOK should be a symbol, and FUNCTION may be any valid function.  If
  128. HOOK is void, it is first set to nil.  If HOOK's value is a single
  129. function, it is changed to a list of functions."
  130.   ;(interactive "SAdd to hook-var (symbol): \naAdd which function to %s? ")
  131.   (if (not (boundp hook)) (set hook nil))
  132.   ;; If the hook value is a single function, turn it into a list.
  133.   (let ((old (symbol-value hook)))
  134.     (if (or (not (listp old)) (eq (car old) 'lambda))
  135.     (setq old (list old)))
  136.     (if (member function old)
  137.     nil
  138.       (set hook (if append
  139.             (append old (list function)) ; don't nconc
  140.           (cons function old))))))
  141.  
  142. (defun remove-hook (hook function)
  143.   "Remove from the value of HOOK the function FUNCTION.
  144. HOOK should be a symbol, and FUNCTION may be any valid function.  If
  145. FUNCTION isn't the value of HOOK, or, if FUNCTION doesn't appear in the
  146. list of hooks to run in HOOK, then nothing is done.  See `add-hook'."
  147.   (if (or (not (boundp hook))        ;unbound symbol, or
  148.       (null (symbol-value hook))    ;value is nil, or
  149.       (null function))        ;function is nil, then
  150.       nil                ;Do nothing.
  151.     (let ((hook-value (symbol-value hook)))
  152.       (if (consp hook-value)
  153.       ;; don't side-effect the list
  154.       (setq hook-value (delete function (copy-sequence hook-value)))
  155.     (if (equal hook-value function)
  156.         (setq hook-value nil)))
  157.       (set hook hook-value))))
  158.  
  159. ;; called by Fkill_buffer()
  160. (defvar kill-buffer-hook nil
  161.   "Function or functions to be called when a buffer is killed.
  162. The value of this variable may be buffer-local.
  163. The buffer about to be killed is current when this hook is run.")
  164.  
  165. ;; in C in FSFmacs
  166. (defvar kill-emacs-hook nil
  167.   "Function or functions to be called when `kill-emacs' is called,
  168. just before emacs is actually killed.")
  169.  
  170.  
  171. ;;;; List functions.
  172.  
  173. (defalias 'first 'car)
  174. (defalias 'rest 'cdr)
  175. (defalias 'endp 'null)
  176.  
  177. (defsubst second (x)
  178.   "Return the second element of the list LIST."
  179.   (car (cdr x)))
  180.  
  181. (defsubst third (x)
  182.   "Return the third element of the list LIST."
  183.   (car (cdr (cdr x))))
  184.  
  185. (defsubst fourth (x)
  186.   "Return the fourth element of the list LIST."
  187.   (nth 3 x))
  188.  
  189. (defsubst fifth (x)
  190.   "Return the fifth element of the list LIST."
  191.   (nth 4 x))
  192.  
  193. (defsubst sixth (x)
  194.   "Return the sixth element of the list LIST."
  195.   (nth 5 x))
  196.  
  197. (defsubst seventh (x)
  198.   "Return the seventh element of the list LIST."
  199.   (nth 6 x))
  200.  
  201. (defsubst eighth (x)
  202.   "Return the eighth element of the list LIST."
  203.   (nth 7 x))
  204.  
  205. (defsubst ninth (x)
  206.   "Return the ninth element of the list LIST."
  207.   (nth 8 x))
  208.  
  209. (defsubst tenth (x)
  210.   "Return the tenth element of the list LIST."
  211.   (nth 9 x))
  212.  
  213. (defsubst caar (x)
  214.   "Return the `car' of the `car' of X."
  215.   (car (car x)))
  216.  
  217. (defsubst cadr (x)
  218.   "Return the `car' of the `cdr' of X."
  219.   (car (cdr x)))
  220.  
  221. (defsubst cdar (x)
  222.   "Return the `cdr' of the `car' of X."
  223.   (cdr (car x)))
  224.  
  225. (defsubst cddr (x)
  226.   "Return the `cdr' of the `cdr' of X."
  227.   (cdr (cdr x)))
  228.  
  229. (defsubst caaar (x)
  230.   "Return the `car' of the `car' of the `car' of X."
  231.   (car (car (car x))))
  232.  
  233. (defsubst caadr (x)
  234.   "Return the `car' of the `car' of the `cdr' of X."
  235.   (car (car (cdr x))))
  236.  
  237. (defsubst cadar (x)
  238.   "Return the `car' of the `cdr' of the `car' of X."
  239.   (car (cdr (car x))))
  240.  
  241. (defsubst caddr (x)
  242.   "Return the `car' of the `cdr' of the `cdr' of X."
  243.   (car (cdr (cdr x))))
  244.  
  245. (defsubst cdaar (x)
  246.   "Return the `cdr' of the `car' of the `car' of X."
  247.   (cdr (car (car x))))
  248.  
  249. (defsubst cdadr (x)
  250.   "Return the `cdr' of the `car' of the `cdr' of X."
  251.   (cdr (car (cdr x))))
  252.  
  253. (defsubst cddar (x)
  254.   "Return the `cdr' of the `cdr' of the `car' of X."
  255.   (cdr (cdr (car x))))
  256.  
  257. (defsubst cdddr (x)
  258.   "Return the `cdr' of the `cdr' of the `cdr' of X."
  259.   (cdr (cdr (cdr x))))
  260.  
  261. (defsubst caaaar (x)
  262.   "Return the `car' of the `car' of the `car' of the `car' of X."
  263.   (car (car (car (car x)))))
  264.  
  265. (defsubst caaadr (x)
  266.   "Return the `car' of the `car' of the `car' of the `cdr' of X."
  267.   (car (car (car (cdr x)))))
  268.  
  269. (defsubst caadar (x)
  270.   "Return the `car' of the `car' of the `cdr' of the `car' of X."
  271.   (car (car (cdr (car x)))))
  272.  
  273. (defsubst caaddr (x)
  274.   "Return the `car' of the `car' of the `cdr' of the `cdr' of X."
  275.   (car (car (cdr (cdr x)))))
  276.  
  277. (defsubst cadaar (x)
  278.   "Return the `car' of the `cdr' of the `car' of the `car' of X."
  279.   (car (cdr (car (car x)))))
  280.  
  281. (defsubst cadadr (x)
  282.   "Return the `car' of the `cdr' of the `car' of the `cdr' of X."
  283.   (car (cdr (car (cdr x)))))
  284.  
  285. (defsubst caddar (x)
  286.   "Return the `car' of the `cdr' of the `cdr' of the `car' of X."
  287.   (car (cdr (cdr (car x)))))
  288.  
  289. (defsubst cadddr (x)
  290.   "Return the `car' of the `cdr' of the `cdr' of the `cdr' of X."
  291.   (car (cdr (cdr (cdr x)))))
  292.  
  293. (defsubst cdaaar (x)
  294.   "Return the `cdr' of the `car' of the `car' of the `car' of X."
  295.   (cdr (car (car (car x)))))
  296.  
  297. (defsubst cdaadr (x)
  298.   "Return the `cdr' of the `car' of the `car' of the `cdr' of X."
  299.   (cdr (car (car (cdr x)))))
  300.  
  301. (defsubst cdadar (x)
  302.   "Return the `cdr' of the `car' of the `cdr' of the `car' of X."
  303.   (cdr (car (cdr (car x)))))
  304.  
  305. (defsubst cdaddr (x)
  306.   "Return the `cdr' of the `car' of the `cdr' of the `cdr' of X."
  307.   (cdr (car (cdr (cdr x)))))
  308.  
  309. (defsubst cddaar (x)
  310.   "Return the `cdr' of the `cdr' of the `car' of the `car' of X."
  311.   (cdr (cdr (car (car x)))))
  312.  
  313. (defsubst cddadr (x)
  314.   "Return the `cdr' of the `cdr' of the `car' of the `cdr' of X."
  315.   (cdr (cdr (car (cdr x)))))
  316.  
  317. (defsubst cdddar (x)
  318.   "Return the `cdr' of the `cdr' of the `cdr' of the `car' of X."
  319.   (cdr (cdr (cdr (car x)))))
  320.  
  321. (defsubst cddddr (x)
  322.   "Return the `cdr' of the `cdr' of the `cdr' of the `cdr' of X."
  323.   (cdr (cdr (cdr (cdr x)))))
  324.  
  325. (defun last (x &optional n)
  326.   "Returns the last link in the list LIST.
  327. With optional argument N, returns Nth-to-last link (default 1)."
  328.   (if n
  329.       (let ((m 0) (p x))
  330.     (while (consp p) (setq m (1+ m)) (pop p))
  331.     (if (<= n 0) p
  332.       (if (< n m) (nthcdr (- m n) x) x)))
  333.     (while (consp (cdr x)) (pop x))
  334.     x))
  335.  
  336. (defun butlast (x &optional n)
  337.   "Returns a copy of LIST with the last N elements removed."
  338.   (if (and n (<= n 0)) x
  339.     (nbutlast (copy-sequence x) n)))
  340.  
  341. (defun nbutlast (x &optional n)
  342.   "Modifies LIST to remove the last N elements."
  343.   (let ((m (length x)))
  344.     (or n (setq n 1))
  345.     (and (< n m)
  346.      (progn
  347.        (if (> n 0) (setcdr (nthcdr (- (1- m) n) x) nil))
  348.        x))))
  349.  
  350. ;;; these are just so convenient in while loops...  The CL package will
  351. ;;; overload these with compatible but more powerful cousins.
  352.  
  353. (defmacro push (val list)
  354.   "Insert VAL at the head of LIST.
  355. Analogous to (setq LIST (cons VAL LIST))."
  356.   `(setq ,list (cons ,val ,list)))
  357.  
  358. (defmacro pop (list)
  359.   "Remove and return the head of LIST.
  360. Analogous to (prog1 (car LIST) (setq LIST (cdr LIST)))."
  361.   `(prog1 (car ,list) (setq ,list (cdr ,list))))
  362.  
  363. ;; not obsolete.
  364. (define-function 'rplaca 'setcar)
  365. (define-function 'rplacd 'setcdr)
  366.  
  367.  
  368. ;;;; Mapping functions.
  369.  
  370. (defun some (__predicate __seq)
  371.   "Return true if PREDICATE is true of any element of SEQ.
  372. If so, return the true (non-nil) value returned by PREDICATE."
  373.   (let ((__x nil))
  374.     (while (and __seq
  375.         (not (setq __x (funcall __predicate (pop __seq))))))
  376.     __x))
  377.  
  378. (defun every (__predicate __seq)
  379.   "Return true if PREDICATE is true of every element of SEQ."
  380.   (while (and __seq (funcall __predicate (car __seq)))
  381.     (setq __seq (cdr __seq)))
  382.   (null __seq))
  383.  
  384. (defun notany (__predicate __seq)
  385.   "Return true if PREDICATE is false of every element of SEQ."
  386.   (not (apply 'some __predicate __seq)))
  387.  
  388. (defun notevery (__predicate __seq)
  389.   "Return true if PREDICATE is false of some element of SEQ."
  390.   (not (apply 'every __predicate __seq)))
  391.  
  392. (defun mapvector (__function __seq)
  393.   "Apply FUNCTION to each element of SEQ, making a vector of the results.
  394. The result is a vector of the same length as SEQ.
  395. SEQ may be a list, a vector or a string."
  396.   (let* ((len (length __seq))
  397.      (vec (make-vector len 'nil))
  398.      (i 0))
  399.     (while (< i len)
  400.       (aset vec i (funcall __function (cond ((listp __seq)
  401.                          (nth i __seq))
  402.                         (t (aref __seq i)))))
  403.       (setq i (+ i 1)))
  404.     vec))
  405.  
  406.  
  407. ;;;; Set functions -- less powerful equivalents of the Common Lisp ones.
  408.  
  409. (defun adjoin (item list)
  410.   "Add ITEM to LIST (unless it's already there) and return the new list."
  411.   (if (memq item list) list (cons item list)))
  412.  
  413. (defun union (list1 list2)
  414.   "Return a list of elements that appear in either LIST1 or LIST2."
  415.   (cond ((null list1) list2) ((null list2) list1)
  416.     ((equal list1 list2) list1)
  417.     (t
  418.      (while list2
  419.        (setq list1 (adjoin (car list2) list1))
  420.        (setq list2 (cdr list2)))
  421.      list1)))
  422.  
  423. (defun intersection (list1 list2)
  424.   "Return a list of elements that appear in both LIST1 and LIST2."
  425.   (and list1 list2
  426.        (if (equal list1 list2) list1
  427.      (let ((result nil))
  428.        (while list2
  429.          (if (memq (car list2) list1)
  430.          (setq result (cons (car list2) result)))
  431.          (setq list2 (cdr list2)))
  432.        result))))
  433.  
  434. (defun set-difference (list1 list2)
  435.   "Return a list of elements of LIST1 that do not appear in LIST2."
  436.   (if (or (null list1) (null list2)) list1
  437.     (let ((list1 (copy-sequence list1)))
  438.       (while list2
  439.     (setq list1 (delq (car list2) list1))
  440.     (setq list2 (cdr list2)))
  441.       list1)))
  442.  
  443. (defun set-exclusive-or (list1 list2)
  444.   "Return a list of elements that appear in exactly one of LIST1 and LIST2."
  445.   (cond ((null list1) list2) ((null list2) list1)
  446.     ((equal list1 list2) nil)
  447.     (t (append (set-difference list1 list2)
  448.            (set-difference list2 list1)))))
  449.  
  450. (defun subsetp (list1 list2)
  451.   "True if every element of LIST1 also appears in LIST2."
  452.   (cond ((null list1) t) ((null list2) nil)
  453.     ((equal list1 list2) t)
  454.     (t (while (and list1
  455.                (memq (car list1) list2))
  456.          (setq list1 (cdr list1)))
  457.        (null list1))))
  458.  
  459. ;;;; String functions.
  460.  
  461. (defun replace-in-string (str regexp newtext &optional literal)
  462.   "Replaces all matches in STR for REGEXP with NEWTEXT string.
  463. Optional LITERAL non-nil means do a literal replacement.
  464. Otherwise treat \\ in NEWTEXT string as special:
  465.   \\& means substitute original matched text,
  466.   \\N means substitute match for \(...\) number N,
  467.   \\\\ means insert one \\."
  468.   (if (not (stringp str))
  469.       (error "(replace-in-string): First argument must be a string: %s" str))
  470.   (if (stringp newtext)
  471.       nil
  472.     (error "(replace-in-string): 3rd arg must be a string: %s"
  473.        newtext))
  474.   (let ((rtn-str "")
  475.     (start 0)
  476.     (special)
  477.     match prev-start)
  478.     (while (setq match (string-match regexp str start))
  479.       (setq prev-start start
  480.         start (match-end 0)
  481.         rtn-str
  482.         (concat
  483.           rtn-str
  484.           (substring str prev-start match)
  485.           (cond (literal newtext)
  486.             (t (mapconcat
  487.              (function
  488.                (lambda (c)
  489.                  (if special
  490.                  (progn
  491.                    (setq special nil)
  492.                    (cond ((eq c ?\\) "\\")
  493.                      ((eq c ?&)
  494.                       (substring str
  495.                              (match-beginning 0)
  496.                              (match-end 0)))
  497.                      ((and (>= c ?0) (<= c ?9))
  498.                       (if (> c (+ ?0 (length
  499.                                (match-data))))
  500.                           ;; Invalid match num
  501.                           (error "(replace-in-string) Invalid match num: %c" c)
  502.                         (setq c (- c ?0))
  503.                         (substring str
  504.                                (match-beginning c)
  505.                                (match-end c))))
  506.                      (t (char-to-string c))))
  507.                    (if (eq c ?\\) (progn (setq special t) nil)
  508.                  (char-to-string c)))))
  509.              newtext ""))))))
  510.     (concat rtn-str (substring str start))))
  511.  
  512. (defun split-string (string pattern)
  513.   "Return a list of substrings of STRING which are separated by PATTERN."
  514.   (let (parts (start 0))
  515.     (while (string-match pattern string start)
  516.       (setq parts (cons (substring string start (match-beginning 0)) parts)
  517.         start (match-end 0)))
  518.     (nreverse (cons (substring string start) parts))
  519.     ))
  520.  
  521. (defmacro with-output-to-string (&rest forms)
  522.   "Collect output to `standard-output' while evaluating FORMS and return
  523. it as a string."
  524.   ;; by "William G. Dubuque" <wgd@zurich.ai.mit.edu> w/ mods from Stig
  525.   (` (save-excursion
  526.        (set-buffer (get-buffer-create " *string-output*"))
  527.        (setq buffer-read-only nil)
  528.        (buffer-disable-undo (current-buffer))
  529.        (erase-buffer)
  530.        (let ((standard-output (current-buffer)))
  531.      (,@ forms))
  532.        (prog1
  533.        (buffer-string)
  534.      (erase-buffer)))))
  535.  
  536. (defun insert-face (string face)
  537.   "Insert STRING and highlight with FACE.  Returns the extent created."
  538.   (let ((p (point)) ext)
  539.     (insert string)
  540.     (setq ext (make-extent p (point)))
  541.     (set-extent-face ext face)
  542.     ext))
  543.  
  544. ;; not obsolete.
  545. (define-function 'string= 'string-equal)
  546. (define-function 'string< 'string-lessp)
  547. (define-function 'int-to-string 'number-to-string)
  548. (define-function 'string-to-int 'string-to-number)
  549.  
  550.  
  551. ;;;; Miscellanea.
  552.  
  553. (defun ignore (&rest ignore)
  554.   "Do nothing and return nil.
  555. This function accepts any number of arguments, but ignores them."
  556.   (interactive)
  557.   nil)
  558.  
  559. (defun error (&rest args)
  560.   "Signal an error, making error message by passing all args to `format'.
  561. This error is not continuable: you cannot continue execution after the
  562. error using the debugger `r' command.  See also `cerror'."
  563.   (while t
  564.     (apply 'cerror args)))
  565.  
  566. (defun cerror (&rest args)
  567.   "Like `error' but signals a continuable error."
  568.   (signal 'error (list (apply 'format args))))
  569.  
  570. (defmacro check-argument-type (predicate argument)
  571.   "Check that ARGUMENT satisfies PREDICATE.
  572. If not, signal a continuable `wrong-type-argument' error until the
  573. returned value satifies PREDICATE, and assign the returned value
  574. to ARGUMENT."
  575.   `(if (not (,(eval predicate) ,argument))
  576.        (setq ,argument
  577.          (wrong-type-argument ,predicate ,argument))))
  578.  
  579. (defmacro save-current-buffer (&rest forms)
  580.   "Restore the current buffer setting after executing FORMS.
  581. Does not restore the values of point and mark.
  582. See also: `save-excursion'."
  583.   ;; by Stig@hackvan.com
  584.   (` (let ((_cur_buf_ (current-buffer)))
  585.        (unwind-protect
  586.        (progn (,@ forms))
  587.      (set-buffer _cur_buf_)))))
  588.  
  589. (defmacro eval-in-buffer (buffer &rest forms)
  590.   "Evaluate FORMS in BUFFER.
  591. See also: `save-current-buffer' and `save-excursion'."
  592.   ;; by Stig@hackvan.com
  593.   (` (save-current-buffer
  594.       (set-buffer (, buffer))
  595.       (,@ forms))))
  596.  
  597. ;;; The real defn is in abbrev.el but some early callers
  598. ;;;  (eg lisp-mode-abbrev-table) want this before abbrev.el is loaded...
  599.  
  600. (if (not (fboundp 'define-abbrev-table))
  601.     (progn
  602.       (setq abbrev-table-name-list '())
  603.       (fset 'define-abbrev-table (function (lambda (name defs)
  604.                                    ;; These are fixed-up when abbrev.el loads.
  605.                                    (setq abbrev-table-name-list
  606.                                          (cons (cons name defs)
  607.                                                abbrev-table-name-list)))))))
  608.  
  609. (defun functionp (obj)
  610.   "Returns t if OBJ is a function, nil otherwise."
  611.   (cond
  612.    ((symbolp obj) (fboundp obj))
  613.    ((subrp obj))
  614.    ((compiled-function-p obj))
  615.    ((consp obj)
  616.     (if (eq (car obj) 'lambda) (listp (car (cdr obj)))))
  617.    (t nil)))
  618.  
  619. (defun add-to-list (list-var element)
  620.   "Add to the value of LIST-VAR the element ELEMENT if it isn't there yet.
  621. If you want to use `add-to-list' on a variable that is not defined
  622. until a certain package is loaded, you should put the call to `add-to-list'
  623. into a hook function that will be run only after loading the package.
  624. Major mode hooks are one thing which can do the job."
  625.   (or (member element (symbol-value list-var))
  626.       (set list-var (cons element (symbol-value list-var)))))
  627.  
  628. ;; This was not present before.  I think Jamie had some objections
  629. ;; to this, so I'm leaving this undefined for now. --ben
  630.  
  631. ;;; The objection is this: there is more than one way to load the same file.
  632. ;;; "foo", "foo.elc", "foo.el", and "/some/path/foo.elc" are all differrent
  633. ;;; ways to load the exact same code.  `eval-after-load' is too stupid to
  634. ;;; deal with this sort of thing.  If this sort of feature is desired, then
  635. ;;; it should work off of a hook on `provide'.  Features are unique and
  636. ;;; the arguments to (load) are not.  --Stig
  637.  
  638. ;;;; Specifying things to do after certain files are loaded.
  639.  
  640. ;(defun eval-after-load (file form)
  641. ;  "Arrange that, if FILE is ever loaded, FORM will be run at that time.
  642. ;This makes or adds to an entry on `after-load-alist'.
  643. ;It does nothing if FORM is already on the list for FILE.
  644. ;FILE should be the name of a library, with no directory name."
  645. ;  (or (assoc file after-load-alist)
  646. ;      (setq after-load-alist (cons (list file) after-load-alist)))
  647. ;  (let ((elt (assoc file after-load-alist)))
  648. ;    (or (member form (cdr elt))
  649. ;    (nconc elt (list form))))
  650. ;  form)
  651. ;
  652. ;(defun eval-next-after-load (file)
  653. ;  "Read the following input sexp, and run it whenever FILE is loaded.
  654. ;This makes or adds to an entry on `after-load-alist'.
  655. ;FILE should be the name of a library, with no directory name."
  656. ;  (eval-after-load file (read)))
  657.  
  658. ; alternate names (not obsolete)
  659. (if (not (fboundp 'mod)) (define-function 'mod '%))
  660. (define-function 'move-marker 'set-marker)
  661. (define-function 'beep 'ding) ;preserve lingual purtity
  662. (define-function 'indent-to-column 'indent-to)
  663. (define-function 'backward-delete-char 'delete-backward-char)
  664. (define-function 'search-forward-regexp (symbol-function 're-search-forward))
  665. (define-function 'search-backward-regexp (symbol-function 're-search-backward))
  666. (define-function 'remove-directory 'delete-directory)
  667. (define-function 'set-match-data 'store-match-data)
  668. (define-function 'send-string-to-terminal 'external-debugging-output)
  669. (define-function 'buffer-string 'buffer-substring)
  670.